package com.example.recordingpen_datacollection.controller;
import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.recordingpen_datacollection.Utils.AIUtil.*;
import com.example.recordingpen_datacollection.Utils.VerifyUtil.StrVerify;
import com.example.recordingpen_datacollection.Utils.http.Messages;
import com.example.recordingpen_datacollection.entity.Login;
import com.example.recordingpen_datacollection.entity.Vo.AIZFYVo;
import com.example.recordingpen_datacollection.entity.Vo.AiWatchVo;
import com.example.recordingpen_datacollection.redisService.RedisService;
import com.example.recordingpen_datacollection.result.RLIST;
import com.example.recordingpen_datacollection.result.exceptionhandler.BDxception;
import com.example.recordingpen_datacollection.result.exceptionhandler.BDxceptionV2;
import com.example.recordingpen_datacollection.result.exceptionhandler.JWException;
import com.example.recordingpen_datacollection.service.AIService;
import com.example.recordingpen_datacollection.service.BaiduKeyService;
import com.example.recordingpen_datacollection.service.DosageStatisticsService;
import com.example.recordingpen_datacollection.service.LoginService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.example.recordingpen_datacollection.Utils.http.HttpUrl.BDAIurlData;
import static com.example.recordingpen_datacollection.Utils.http.HttpUrl.BDAIurlData_special;

@RestController
@RequestMapping("/AIS")
@Slf4j
public class APITestController {



    @Autowired
    private RedisService redisService;
    @Autowired
    private BaiduKeyService baiduKeyService;
    @Autowired
    private AIService aiService;
    @Autowired
    private DosageStatisticsService dosageStatisticsService;
    @Autowired
    private LoginService loginService;

    @PostMapping(value = "/sse-invoke", produces = "text/event-stream;charset=UTF-8")
    public void sse(@RequestBody AIZFYVo aiSumUp, HttpServletResponse rp) {
        Messages messages = new Messages();
        messages.setContent(aiSumUp.getContent());
        messages.setRole("user");
        List<Messages> messagesList = new ArrayList<>();
        messagesList.add(messages);
        String URL = null;
        ChatGlmDto chatGlmDto = new ChatGlmDto();
        chatGlmDto.setMessages(messagesList);
        chatGlmDto.setMessageId(aiSumUp.getDeviceId());
        String access_token = null;
        if (AIChangeUtil.judgeUtil(aiSumUp.getContent())) {
            URL = BDAIurlData_special;;
            access_token = baiduKeyService.payBDtoken();
        } else {
            URL = BDAIurlData;
            access_token = baiduKeyService.BDtoken();
        }

//        boolean bd_access_token = redisService.getKeyData(BD_ACCESS_TOKEN);
//        String access_token = null;
//        if(!bd_access_token){
//            try {
//                String bDtokenData = BDokHttpUtil.getBDtoken();
//                JSONObject jsonObject = JSON.parseObject(bDtokenData);
//
//                // 从JSONObject中提取值
//                access_token = jsonObject.getString("access_token");
//                int expires_in = jsonObject.getIntValue("expires_in")-(100*1000);
//                redisService.setTokenValue2(BD_ACCESS_TOKEN,expires_in,access_token);
//                System.out.println("重新调用token");
//            } catch (IOException e) {
//                throw new JWException(500,"获取DB_token异常");
//            }
//        } else {
//            access_token = (String)redisService.getValue(BD_ACCESS_TOKEN);
//            System.out.println("没有调用token");
//        }

//        System.out.println("token——》开始时间--》"+System.currentTimeMillis());

//        System.out.println("token——》结束时间--》"+System.currentTimeMillis());
        if(access_token == null){
            throw new JWException(500,"获取key失败");
        }
        try {
            String token = access_token;
            SSEListener sseListener = new SSEListener(chatGlmDto, rp);
            ExecuteSSEUtil.executeSSE(URL, token, sseListener, JSON.toJSONString(chatGlmDto));
        } catch (Exception e) {
            log.error("请求SSE错误处理", e);

        }

    }

    @PostMapping("/stream2")
    @ApiOperation("流式返回")
    public ResponseEntity<StreamingResponseBody> stream() {
        System.out.println("接口开始时间"+System.currentTimeMillis());
        StreamingResponseBody stream = out -> {
            String message = "这是假数据";
            for (int i = 0; i < message.length(); i++) {
                try {
                    out.write((message + i).getBytes());
                    Thread.sleep(1000);
                    // 发送回复
                    out.flush();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        return ResponseEntity.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(stream);
    }
    @ApiOperation("流式返回2")
    @GetMapping("/stream")
    public SseEmitter handleSse() {
        System.out.println("接口开始时间"+System.currentTimeMillis());
        SseEmitter emitter = new SseEmitter();
// 在新线程中发送事件以避免阻塞主线程
        new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    Map<String, Object> eventData = new HashMap<>();
                    eventData.put("id", i);
                    eventData.put("message", "Hello, SSE " + i);
                    emitter.send(eventData);
                    System.out.println("message");
                    Thread.sleep(1000); // 每秒发送一次
                }
                emitter.complete(); // 完成事件流发送
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e); // 发送错误
            }
        }).start();
        return emitter;
    }

    @ApiOperation("流式返回2")
    @GetMapping("/data")
    public RLIST data() {
        System.out.println("接口开始时间"+System.currentTimeMillis());
        return RLIST.ok();
    }


    @ApiOperation("手表测试接口")
    @PostMapping("/watch")
    public JSONObject watch(@RequestBody AiWatchVo watchVo) {
        if(watchVo.getDevId().isEmpty() || watchVo.getDevId().isEmpty()){
            BDxceptionV2 bDxception = new BDxceptionV2(33602, "The device Id is not allowed to be empty");
            JSONObject jsonObject = (JSONObject)JSONObject.toJSON(bDxception);
            return jsonObject;

//            throw new BDxception(33602, "The device Id is not allowed to be empty");

        }
        if(watchVo.getDevId().contains(" ")){
            BDxceptionV2 bDxception = new BDxceptionV2(33602, "Device ids are not allowed to contain Spaces");
            JSONObject jsonObject = (JSONObject)JSONObject.toJSON(bDxception);
            return jsonObject;
//            throw new BDxception(33602, "Device ids are not allowed to contain Spaces");
        }
        if(watchVo.getContent().isEmpty() || watchVo.getContent().isEmpty()){
            BDxceptionV2 bDxception = new BDxceptionV2(33602, "content is not allowed to be empty");
            JSONObject jsonObject = (JSONObject)JSONObject.toJSON(bDxception);
            return jsonObject;
//            throw new BDxception(33602, "content is not allowed to be empty");
        }

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("account",watchVo.getDevId());
        Login one = loginService.getOne(wrapper);
        if(one == null){
            BDxceptionV2 bDxception = new BDxceptionV2(33602, "Device does not exist");
            JSONObject jsonObject = (JSONObject)JSONObject.toJSON(bDxception);
            return jsonObject;
        }

        Map<String, Object> map = StrVerify.conferenceInformation(watchVo.getContent());
        System.out.println(map);
        if(map != null){
            boolean fale = (boolean)map.get("fale");
            if(fale){
                JSONObject txtAiWatch=dosageStatisticsService.getConference(map, String.valueOf(one.getId()));
                return txtAiWatch;
            }
        }

        JSONObject txtAiWatch= aiService.txtAiWatch(watchVo);

        return txtAiWatch;
    }
//

    @ApiOperation("手表测试接口流式")
    @PostMapping("/watchStream")
    public JSONObject watchStream(@RequestBody AiWatchVo watchVo, HttpServletResponse rp, HttpServletRequest request){

        if(watchVo.getDevId().isEmpty() || watchVo.getDevId().isEmpty()){
            throw new BDxception(33602, "The device Id is not allowed to be empty");


//            throw new BDxception(33602, "The device Id is not allowed to be empty");

        }
        if(watchVo.getDevId().contains(" ")){
            throw new BDxception(33602, "Device ids are not allowed to contain Spaces");

//            throw new BDxception(33602, "Device ids are not allowed to contain Spaces");
        }
        if(watchVo.getContent().isEmpty() || watchVo.getContent().isEmpty()){
            throw new BDxception(33602, "content is not allowed to be empty");

//            throw new BDxception(33602, "content is not allowed to be empty");
        }
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("account",watchVo.getDevId());
        Login one = loginService.getOne(wrapper);
        if(one == null){
            throw new BDxception(33602, "Device does not exist");

        }

        Map<String, Object> map = StrVerify.conferenceInformation(watchVo.getContent());
        if(map != null){
            boolean fale = (boolean)map.get("fale");
            if(fale){

                JSONObject txtAiWatch=dosageStatisticsService.getConferenceV2(map, String.valueOf(one.getId()));
                try {
                    rp.setContentType("text/event-stream");
                    rp.setCharacterEncoding("UTF-8");
                    rp.setStatus(200);
                    rp.getWriter().write("data:" + txtAiWatch + "\n");
                    rp.getWriter().flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }


                return null;
            }
        }

        aiService.BDERNIE_stream(watchVo, rp);
        return null;
    }
}

